// // zdl:: 代码量变多了

// #include<iostream>
// #include<vector>
// #include<algorithm>
// #include<queue>
// #include<cstring>
// using namespace std;
// queue<int> q;
// const int N = 1e4 + 10, inf = 0x3f3f3f3f;
// vector<int> e1[N];
// vector<int> e2[N];
// bool st[N];
// int f[N];
// int n, m;
// int s, t;
// void dfs(int pos)
// {
//     st[pos] = true;
//     for (auto& x : e2[pos])
//     {
//         if (!st[x]) dfs(x);
//     }
// }

// bool check(int x)
// {
//     if (!st[x]) return false;
//     for (auto& y : e1[x])
//     {
//         if (!st[y]) return false;
//     }
//     return true;
// }
// // zdl:: 接口下来开始打表
// int bfs(int s)
// {

//     memset(f, 0x3f, sizeof f);
//     if (!check(s)) return -1;
//     q.push(s);
//     f[s] = 0;
//     while (q.size())
//     {
//         auto x = q.front(); q.pop();
//         for (auto y: e1[x])
//         {
//             if (!check(y) || f[y] != inf) continue;
//             f[y] = min(f[y], f[x] + 1);
//             q.emplace(y);
//         }
//     }

//     if (f[t] == inf) return -1;
//     else return f[t];
// }
// int main()
// {
//     cin >> n >> m;
//     for (int i = 1; i <= m; i++)
//     {
//         int x, y; cin >> x >> y;
//         // 想要知道终点能不能到达这个点，需要建返图
//         e1[x].emplace_back(y);
//         e2[y].emplace_back(x);
//     }
//     cin >> s >> t;
//     dfs(t);

//     cout << bfs(s) << endl;
//     return 0;
// }


#include<iostream>


using namespace std;


int main()
{
    int n; cin >> n;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            cout << i << "*" << j << "=" << i * j << "\t";
        }
        cout << endl;
    }
    return 0;
}